import { BadRequestException, Controller,   Get, Headers, Inject, Query, UnauthorizedException } from '@nestjs/common';
import { randomUUID } from 'crypto';
import * as qrcode from 'qrcode';
import { JwtService } from '@nestjs/jwt';


const map = new Map<string, QrCodeInfo>();

interface QrCodeInfo {
    status: 'noscan' | 'scan-wait-confirm' | 'scan-confirm' | 'scan-cancel' | 'expired',
    userInfo?: {
        userId: number;
    }
}

@Controller('qrcode')
export class QrcodeController {

    @Inject(JwtService)
    private jwtService: JwtService;

    private users = [
        { id: 1, username: 'dong', password: '111' },
        { id: 2, username: 'guang', password: '222' },
    ];


    @Get('generate')
    async generate() {
        const uuid = randomUUID();
        const dataUrl = await qrcode.toDataURL(`http://10.0.20.253:3000/pages/confirm.html?id=${uuid}`); // 返回带有本地登录页面的url地址 注入到二维码
        return {
            qrcode_id: uuid,
            img: dataUrl
        }
    }

    // 查询二维码的状态
    @Get('qrcode/check')
    async check(@Query('id') id: string) {
        const info = map.get(`qrcode_${id}`);
        if (info.status === 'scan-confirm') {
            return {
                token: this.jwtService.sign({
                    userId: info.userInfo.userId
                }),
                ...info
            }
        }
        return info;
    }


    @Get('qrcode/scan')
    async scan(@Query('id') id: string) {
        const info = map.get(`qrcode_${id}`);
        if (!info) {
            throw new BadRequestException('二维码已过期');
        }
        info.status = 'scan-wait-confirm';
        return 'success';
    }

    @Get('qrcode/confirm')
    async confirm(@Query('id') id: string, @Headers('Authorization') auth: string) {
        let user;
        try {
            const [, token] = auth.split(' ');
            const info = await this.jwtService.verify(token);

            user = this.users.find(item => item.id == info.userId);
        } catch (e) {
            throw new UnauthorizedException('token 过期，请重新登录');
        }

        const info = map.get(`qrcode_${id}`);
        if (!info) {
            throw new BadRequestException('二维码已过期');
        }
        info.status = 'scan-confirm';
        info.userInfo = user;
        return 'success';
    }

    @Get('qrcode/cancel')
    async cancel(@Query('id') id: string) {
        const info = map.get(`qrcode_${id}`);
        if (!info) {
            throw new BadRequestException('二维码已过期');
        }
        info.status = 'scan-cancel';
        return 'success';
    }




    @Get('login')
    async login(@Query('username') username: string, @Query('password') password: string) {

        const user = this.users.find(item => item.username === username);

        if (!user) {
            throw new UnauthorizedException('用户不存在');
        }
        if (user.password !== password) {
            throw new UnauthorizedException('密码错误');
        }

        return {
            token: await this.jwtService.sign({
                userId: user.id
            })
        }
    }

    // 拿到用户信息
    @Get('userInfo')
    async userInfo(@Headers('Authorization') auth: string) {
        try {
            const [, token] = auth.split(' ');
            const info = await this.jwtService.verify(token);

            const user = this.users.find(item => item.id == info.userId);
            return user;
        } catch (e) {
            throw new UnauthorizedException('token 过期，请重新登录');
        }
    }


}
